package com.example.demo.ws;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.concurrent.*;

import static com.example.demo.ws.WsInterceptor.ATTR_KEY_USER_ID;

/**
 * ws模式
 * file:///Users/yuanby/yby/gitee/前端/websocketDemo.html
 */
@Component
public class WsHandler extends TextWebSocketHandler {//AbstractWebSocketHandler
    private static final Logger log = LoggerFactory.getLogger(WsHandler.class);
    private final ConcurrentHashMap<Long, WebSocketSession> sessionByUserIdMap = new ConcurrentHashMap<>();
    private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

    public boolean sendMessageByUserId(long userId, String msg) {
        try {
            WebSocketSession session = sessionByUserIdMap.get(userId);
            if (session == null || !session.isOpen()) {
                return false;
            }
            session.sendMessage(new TextMessage(msg));
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    /**
     * 连接建立把用户id 跟连接关联起来存入缓存
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        log.info("afterConnectionEstablished sid: {}, uri: {}", session.getId(), session.getUri());
        Long userId = (Long) session.getAttributes().get(ATTR_KEY_USER_ID);
        sessionByUserIdMap.put(userId, session);
    }

    /**
     * 处理消息
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        log.info("handleMessage sid: {}, msg: {}", session.getId(), message);

        Long userId = (Long) session.getAttributes().get(ATTR_KEY_USER_ID);
        String text = message.getPayload();
        executorService.schedule(() -> {
            log.info("计算并发送消息");
            String result = WebPollController.sha256(text);
            sessionByUserIdMap.get(userId).sendMessage(new TextMessage("输入：" + text + "，输出：" + result));
            return 0;
        }, 2, TimeUnit.SECONDS);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.info("handleTransportError sid: {}", session.getId());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        log.info("afterConnectionClosed sid: {}", session.getId());
        sessionByUserIdMap.remove(session.getId());
    }

    @Override
    public boolean supportsPartialMessages() {
        log.info("supportsPartialMessages");
        return super.supportsPartialMessages();
    }
}
